#pragma once

#include "noncopyable.h"
#include "TimeStamp.h"

#include <functional>
#include <memory>

using std::shared_ptr;
using std::weak_ptr;

class EventLoop;
// 对fd的事件封装 仅关注fd的事件分发 不涉及具体业务逻辑
class Channel : noncopyable
{
public:
    using EventCallback = std::function<void()>;
    using ReadEventCallback = std::function<void(TimeStamp)>;

    Channel(EventLoop *loop, int fd);
    ~Channel();

    int fd() const { return _fd; }
    int events() const { return _events; }
    void set_revents(int revt) { _revents = revt; } // pollers调用

    int index() const { return _index; }
    void set_index(int index) { _index = index; }
    bool isNoneEvent() const { return _events == kNoneEvent; }

    // 将Channel对象和一个由shared_ptr管理的owner对象(如TcpConnection)绑定
    // 在Channel处理事件回调（如handleEvent）时,防止所有者对象被意外析构,从而避免悬空指针或内存访问错误
    void tie(const shared_ptr<void>&);

    void handleEvent(TimeStamp recvTime);
    void setReadCallback(ReadEventCallback &&cb) { _readCallback = std::move(cb); }
    void setWriteCallback(EventCallback &&cb) { _writeCallback = std::move(cb); }
    void setCloseCallback(EventCallback &&cb) { _closeCallback = std::move(cb); }
    void setErrorCallback(EventCallback &&cb) { _errorCallback = std::move(cb); }

    void enableReading() { _events |= kReadEvent; update(); }
    void disableReading() { _events &= ~kReadEvent; update(); }
    void enableWriting() { _events |= kWriteEvent; update(); }
    void disableWriting() { _events &= ~kWriteEvent; update(); }
    void disableAll() { _events = kNoneEvent; update(); }
    bool isWriting() const { return _events & kWriteEvent; }
    bool isReading() const { return _events & kReadEvent; }

    void doNotLogHup() { _logHup = false; }
    EventLoop* ownerLoop() { return _loop; }
    void remove();

    string reventsToString() const;
    string eventsToString() const;
private:
    // **通知EventLoop更新当前Channel事件监听状态
    void update(); 

    static string eventsToString(int fd, int ev);
private:

    EventLoop* _loop; //所属的loop
    const int _fd; // 保管的fd
    int _events; // fd关注事件集合
    int _revents; // fd实际触发事件(Poller设置)
    int _index; // Channel在Poller中的注册状态(新增|已添加|已删除)
    bool _logHup;

    static const int kNoneEvent; // 无事件
    static const int kReadEvent; // 读事件EPOLLIN
    static const int kWriteEvent;// 写事件EPOLLOUT

    weak_ptr<void> _tie;
    bool _tied;
    bool _eventHanding;
    bool _addedToLoop; // 是否添加到EventLoop监听列表
    ReadEventCallback _readCallback;
    EventCallback _writeCallback;
    EventCallback _closeCallback;
    EventCallback _errorCallback;

};

